package com.petdog.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

/**
 * 管理员后台安全配置
 */
@Configuration
@EnableWebSecurity
public class AdminSecurityConfig {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 配置管理员安全过滤链
     */
    @Bean
    public SecurityFilterChain adminSecurityFilterChain(HttpSecurity http) throws Exception {
        http
            // 仅适用于管理员API路径
            .antMatcher("/api/admin/**")
            .authorizeRequests()
                // 允许管理员登录接口无需认证
                .antMatchers(HttpMethod.POST, "/api/admin/login").permitAll()
                // 所有其他管理员接口都需要ADMIN角色
                .anyRequest().hasRole("ADMIN")
                .and()
            // 禁用CSRF（仅用于API）
            .csrf().disable()
            // 使用表单登录
            .formLogin()
                .loginProcessingUrl("/api/admin/login")
                .successHandler((request, response, authentication) -> {
                    response.setContentType("application/json");
                    response.getWriter().write("{\"code\": 200, \"message\": \"登录成功\"}");
                })
                .failureHandler((request, response, exception) -> {
                    response.setContentType("application/json");
                    response.getWriter().write("{\"code\": 401, \"message\": \"登录失败\"}");
                })
                .and()
            // 配置退出登录
            .logout()
                .logoutUrl("/api/admin/logout")
                .logoutSuccessHandler((request, response, authentication) -> {
                    response.setContentType("application/json");
                    response.getWriter().write("{\"code\": 200, \"message\": \"退出成功\"}");
                })
                .and()
            // 配置异常处理
            .exceptionHandling()
                .authenticationEntryPoint((request, response, authException) -> {
                    response.setContentType("application/json");
                    response.getWriter().write("{\"code\": 401, \"message\": \"未授权访问\"}");
                })
                .accessDeniedHandler((request, response, accessDeniedException) -> {
                    response.setContentType("application/json");
                    response.getWriter().write("{\"code\": 403, \"message\": \"权限不足\"}");
                });

        return http.build();
    }

    /**
     * 配置认证提供者
     */
    @Bean
    public DaoAuthenticationProvider adminAuthenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(passwordEncoder);
        return provider;
    }

    /**
     * 配置认证管理器
     */
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(adminAuthenticationProvider());
    }

    /**
     * 提供PasswordEncoder的Bean定义
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder();
    }

    /**
     * 提供UserDetailsService的Bean定义
     */
    @Bean
    public UserDetailsService userDetailsService() {
        // 使用项目中已有的UserServiceImpl实现
        return new com.petdog.module.user.service.impl.UserServiceImpl();
    }
}
